﻿namespace MefContrib.Models.Provider
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition.Primitives;
    using System.Diagnostics;
    using System.Linq;

    /// <summary>
    /// Defines the class for composable part definitions, which describe, and allow the creation
    /// of, <see cref="ProviderComposablePart"/> objects.
    /// </summary>
    public class ProviderComposablePartDefinition : ComposablePartDefinition
    {
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private readonly IEnumerable<ExportDefinition> exports;
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private readonly IEnumerable<ImportDefinition> imports;
        
        /// <summary>
        /// Initializes a new instance of the <see cref="ProviderComposablePartDefinition"/> class.
        /// </summary>
        /// <param name="catalog">The <see cref="DefinitionProviderPartCatalog"/> that the definition is associated with.</param>
        /// <param name="exportDefinitions">A collection of <see cref="ProviderExportDefinition"/> objects.</param>
        /// <param name="importDefinitions">A collection of <see cref="ProviderImportDefinition"/> objects.</param>
        /// <param name="typeName">The fully qualified name of the type for which the definition is created.</param>
        public ProviderComposablePartDefinition(DefinitionProviderPartCatalog catalog, string typeName, IEnumerable<ProviderExportDefinition> exportDefinitions, IEnumerable<ProviderImportDefinition> importDefinitions)
        {
            this.exports = exportDefinitions.Cast<ExportDefinition>();
            this.imports = importDefinitions.Cast<ImportDefinition>();

            this.Catalog = catalog;
            this.Type = Type.GetType(typeName, false);
        }

        /// <summary>
        /// Gets the catalog associated with the definition.
        /// </summary>
        /// <value>A <see cref="DefinitionProviderPartCatalog"/> object.</value>
        public DefinitionProviderPartCatalog Catalog { get; private set; }

        /// <summary>
        /// Gets the type that the definition was created for.
        /// </summary>
        /// <value>A <see cref="Type"/> object.</value>
        public Type Type { get; private set; }

        /// <summary>
        /// Gets a collection of all the export definitions that was discovered for the type.
        /// </summary>
        /// <value>A collection of <see cref="ExportDefinition"/> objects.</value>
        public override IEnumerable<ExportDefinition> ExportDefinitions
        {
            [DebuggerStepThrough]
            get { return this.exports; }
        }

        /// <summary>
        /// Gets a collection of all the import definitions that was discovered for the type.
        /// </summary>
        /// <value>A collection of <see cref="ImportDefinition"/> objects.</value>
        public override IEnumerable<ImportDefinition> ImportDefinitions
        {
            [DebuggerStepThrough]
            get { return this.imports; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override ComposablePart CreatePart()
        {
            return new ProviderComposablePart(this);
        }

        public override string ToString()
        {
            return Type.ToString();
        }
    }
}